
var logLevel = 2;

var XMPP_HOST = 'zy48';
var BOSH_SERVICE = 'http://48.lsu.pw:7070/http-bind/';
var connection = null;

var peerjs;
var peerConnections = {};
var webrtcSupport = false;
var peerFileName;

var xmppPres = {};
xmppPres.online = 'online';
xmppPres.offline = 'offline';
xmppPres.waiting = 'waiting';
xmppPres.chating = 'chating';
xmppPres.afterChat = 'after';
xmppPres.busy = 'busy';
xmppPres.dnd = 'dnd';

var browserType = {};
browserType.chrome = 'chrome';
browserType.firefox = 'firefox';
browserType.opera = 'opera';
browserType.ie = 'ie';
browserType.edge = 'edge';

var systemType = {};
systemType.windows = 'windows';
systemType.linux = 'linux';
systemType.android = 'android';
systemType.ios = 'ios';
systemType.osx = 'osx';
/**
 *
 * fullJid: 'li-service-dnuvhpj3@zy48/comm100'
 * myJid/bareJid/pureJid: 'li-service-dnuvhpj3@zy48'
 * myFullName: 'li-service-dnuvhpj3'
 * myName: 'li'
 */
var myFullJid;
var myJid;
var myFullName;
var myName;
var myPasswd;
var myPres = {show: 'chat', status: 'online'};/*{
                show: 'online', 
                pres: {
                        browser: browserType.chrome, 
                        system: systemType.windows, 
                        ip: '192.168.1.1',
                        location: '浙江丽水'
                      }
             };*/

var siteCode;

var transmitItem;


/**
 * Generate unique id like ->
 *   "bfc7d682_c7f2e1ed_ab0c0193_63b53085"
 *
 * @Source http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript?page=1&tab=votes#answer-105074
 * @return string id.
 */
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
  }

  return s4() + s4() + '_' + s4() + s4() + '_' + s4() + s4() + '_' + s4() + s4();
};


function preventDefault(evt){
  evt.preventDefault();
  evt.stopPropagation();
}

function checkWebrtcSupport() {
  if(navigator.userAgent.search('Chrome') >= 0) {
    webrtcSupport = true;
  } else {
    webrtcSupport = false;
  }
}


function replaceQuoteInString(s) {
  while(s.search('&quot;') >= 0) { s = s.replace('&quot;', '"');}
  return s;
}

/************************************************************************************************************
 * 
 * file functions.
 *
 ***********************************************************************************************************/


var tmpDataUrl;
var fileDataUrlReader = new FileReader();
fileDataUrlReader.onload = function (fileReaderEvent) {
  tmpDataUrl = fileReaderEvent.target.result;
};

function setBlobToImgType(blob) {
  blob = new Blob([blob],{type : 'image/jpeg'})
  return blob;
}


function setBlobToFileType(blob, fileName) {
  var file = new File([blob], fileName)
  return file;
}

function getDataUrlOfFile(file) {
  fileDataUrlReader.readAsDataURL(file);
  return tmpDataUrl;
}

function queryClips() {
  for(name in localStorage) {
    var value = localStorage[name];
    if(name.search('clip-') == 0) {
      addClip(value);
    }
  }
}

function saveClip(clipText) {
  localStorage.setItem('clip-' + clipText, clipText);
}

/***********************************************************************************************************************
 *
 * log functions.
 *
 **********************************************************************************************************************/

function consoleLog(mess, level) {
  if (logLevel >= level) {
    console.log(level + ': ' + mess);
  }
}

/***********************************************************************************************************************
 *
 * DOM functions.
 *
 **********************************************************************************************************************/


function generateEmojiItems() {
  var ul = $('#emoji-box');
  for(i = 1; i < 76; i++) {
    var li = document.createElement('li');
    $(li).attr('class', 'emoji-grid-cell');
    $(li).html('<img class="emoji-image" src="/emoji/qq/' + i + '.gif">');
    $(ul).append(li);
  }
}


function playMessageRingtone() {
  $('.on-message-audio')[0].play();
}

function hideLoginLayer() {
  $('.login-layer-container').hide();
}

function showLoginLayer() {
  $('.login-layer-container').show();
}

function updateLivetime() {
  var countSpans = $('.online-livetime');
  for(i = 0; i < countSpans.length; i++) {
    var countSpan = countSpans[i];
    var timeCount = $(countSpan).html();
    timeCount++;
    $(countSpan).html(timeCount);
  }
  setTimeout("updateLivetime()", 1000);
}


function sendPresSchedule() {
  sendPresence();
  setTimeout("sendPresSchedule()", 10000);
}

function changeCustomStatus(customItem, status) {
  $(customItem).attr('class', 'custom-item ' + status);
}

function changeServiceStatus(serviceFullName, status) {
  $('#' + serviceFullName + '-service-item').attr('class', 'service-item ' + status);
}

function addCustomItem(customFullName, customNick, customStatus, customIp, customLocation, customViewingUrl, customBrowser, customDevice) {
  consoleLog('add a customItem of ' + customFullName);
  customName = customFullName;
  var customItem = $("#" + customName + "-custom-item");
  if(customItem.length == 0) {
    customItem = document.createElement('li');
    customItem = $(customItem);
    customItem.attr('class', 'custom-item ' + customStatus);
    customItem.attr('id', customName + "-custom-item");
    customItem.html('<i class="iconfont custom-avatar">&#xe611;</i>'
                  + '<a class="custom-name" href="javascript:;">' + customNick.substr(0, 8) + '</a><span class="custom-status"></span>'                  
                  + '<span class="online-livetime">0</span>'
                  + '<i class="delete-custom-buttom iconfont">&#xe603;</i>'
                  + '<p class="custom-location-info">'
                  + '<span class="location-ipaddress">' + customIp + '</span>'
                  + '<span class="custom-location-text">' + customLocation + '</span>'
                  + '</p>'
                  + '<p class="custom-viewing-url" '
                  + 'title="' + customViewingUrl + '">'
                  + customViewingUrl
                  + '</p>'
                  + '<i class="iconfont custom-browser-info">&#xe606;</i>'
                  + '<i class="iconfont custom-device-info">&#xe619;</i>');
    $('.custom-list').append(customItem);
  }
  if(customNick) {
    $(customItem).children('.custom-name').html(customNick.substr(0, 8));
    if($('#' + customFullName + '-custom-panel').length > 0) {
      $('#' + customFullName + '-custom-panel').children('.chat-panel-custom-name').html(customNick.substr(0, 8));
    }
  }

  if(customStatus) {
    changeCustomStatus(customItem, customStatus);
  }

  if(customBrowser == browserType.chrome) {
    $(customItem).children('.custom-browser-info').html('&#xe618;');
  } else if(customBrowser == browserType.firefox) {
    $(customItem).children('.custom-browser-info').html('&#xe617;');
  }
/*

  if(customDevice == systemType.windows) {
    $(customItem).children('.custom-device-info').html('&#xe619;');
  }
*/
}

function removeCustomItem(fullName) {
  $('#' + fullName + '-custom-item').remove();
}

function hideChatPanel(chatPanel) {
  $(chatPanel).hide();
}

function removeChatPanel(chatPanel) {
  $(chatPanel).remove();
}

function messageBoardScrollToBottom(messageBoard) {
  if(!messageBoard) {
    messageBoard = $('.chat-panel.active .chat-message-board');
  }
  $(messageBoard).animate({scrollTop: $(messageBoard)[0].scrollHeight}, 100);
}

function appendSystemMessage(message, chatPanel) {
  var messEle = document.createElement('div');
  $(messEle).addClass('system-message');
  $(messEle).html('<span class="system-message-text">' + message + '</span>');
  if(!chatPanel) {
    chatPanel = $('.chat-panel.active');
  }
  $(chatPanel).children('.chat-message-board').append(messEle);
  messageBoardScrollToBottom($(chatPanel).children('.chat-message-board'));
}

/**
 *
 * trans raw text message like 
 *    'alifewjfverio[emoji_12]lseia sliefj[emoji_3]' 
 * to message contain emoji like 
 *    'alifewjfverio<img class="emoji-message" src="./emoji/qq/12.gif">lseia sliefj<img class="emoji-message" src="./emoji/qq/3.gif">'
 *
 */
function transTextMessage(content) {
  while(content.search('\\[emoji_\\d+]') >= 0) {
    var emoji = /\[emoji_\d+]/.exec(content);
    var substitute = /\d+/.exec(emoji);
    substitute = '<img class="emoji-message" src="/emoji/qq/' + substitute + '.gif">';
    content = content.replace(emoji, substitute);
  }
  return content;
}


/**
 *
 * get string representation of current time like "21:06:56 5/9"
 *
 */
function getTimestamp() {
  var d = new Date();
  var h = d.getHours(), m = d.getMinutes(), s = d.getSeconds();
  if(h < 10) {
    h = '0' + h;
  }
  if(m < 10) {
    m = '0' + m;
  }
  if(s < 10) {
    s = '0' + s;
  }
  var ts = h + ':' + m + ':' + s + ' ' + (d.getMonth() + 1) + '/' + d.getDate();
  return ts;
}

function appendHistorySendMessage(name, content, time) {
  var customPanel = $('.chat-panel#' + name + '-custom-panel');
  if($(customPanel).length > 0) {
     var container = document.createElement('div');
    content = transTextMessage(content);
    var date = new Date(time);
    $(container).addClass("message-out");
    $(container).html('<span class="text-message">'
                      + content + '</span>'
                      + '<p class="timestamp">历史消息' + (date.getMonth() + 1) + '/' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '</p>');
    var messageBoard = $(customPanel).children('.chat-message-board')
    $(messageBoard).append(container);
    messageBoardScrollToBottom($(messageBoard));
}
  }
 

function appendHistoryRecieveMessage(name, content, time) {
  var customPanel = $('.chat-panel#' + name + '-custom-panel');
  if($(customPanel).length >= 0) {
  var container = document.createElement('div');
  content = transTextMessage(content);
  var date = new Date(time);
  $(container).addClass("message-in");
  $(container).html('<span class="text-message">'
                    + content + '</span>'
                    + '<p class="timestamp">历史消息' + (date.getMonth() + 1) + '/' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '</p>')
    var messageBoard = $(customPanel).children('.chat-message-board')
    $(messageBoard).append(container);
    messageBoardScrollToBottom($(messageBoard));
}
}


/**
 * Show message on chat board.
 *
 * @param source the sender of the message, 1 for peer, 2 for self. //
 */
function appendMessage(source, content, chatPanel) {
  var container = document.createElement('div');
  content = transTextMessage(content);
  if (source == 1) {
    $(container).addClass("message-in");
    $(container).html('<span class="text-message">'
                    + content + '</span>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>')
  } else if (source == 2) {
    $(container).addClass("message-out");
    $(container).html('<span class="text-message">'
                    + content + '</span>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>')
  } else {
    $(container).addClass("message-in");
        $(container).html('<span class="message-sender">' + source + '</span>'
                    + '<span class="text-message">'
                    + content + '</span>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>')
  }
  if (!chatPanel) {
    $('.chat-panel.active').children('.chat-message-board').append(container);
    messageBoardScrollToBottom($(".chat-panel.active .chat-message-board"));
  } else {
    var messageBoard = $(chatPanel).children('.chat-message-board')
    messageBoardScrollToBottom($(messageBoard));
    $(messageBoard).append(container);
  }
  return true;
}


/**
 * @param messageSource the sender of the message, 1 for peer, 2 for self. TODO: 3 for notify.
 */
function appendImageMessage(source, blobUrl, chatPanel) {
  var container = document.createElement('div');
  if (source == 1) {
    $(container).addClass("message-in");
    $(container).html('<img class="image-message" src="'
                    + blobUrl + '"></img>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>')
  } else if (source == 2) {
    $(container).addClass("message-out");
    $(container).html('<img class="image-message" src="'
                    + blobUrl + '"></img>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>')
  } else {
    $(container).addClass("message-in");
        $(container).html('<span class="message-sender">' + source + '</span>'
                    + '<img class="image-message" src="'
                    + blobUrl + '"></img>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>');
  }
  if (!chatPanel) {
    $('.chat-panel.active').children('.chat-message-board').append(container);
    messageBoardScrollToBottom($(".chat-panel.active .chat-message-board"));
  } else {
    var messageBoard = $(chatPanel).children('.chat-message-board')
    $(messageBoard).append(container);
    messageBoardScrollToBottom($(messageBoard));
  }
}

function appendFileMessage(source, blobUrl, chatPanel) {
  var container = document.createElement('div');
  var download = 'download';
  if(peerFileName) {
    consoleLog('peerFileName set to ' + peerFileName);
    download += '=' + peerFileName;
  }
  if (source == 1) {
    $(container).addClass("message-in");
    $(container).html('<a class="file-download-button" href="' 
                       + blobUrl 
                       + '" ' + download + '><i class="iconfont">&#xe61c;<span class="file-message-download-tip">点击下载文件</span> </i></a>'
                    + '<p class="timestamp">' + getTimestamp() + '</p>')
  } else if (source == 2) {
    $(container).addClass("message-out");
    $(container).html('<a class="file-download-button" href="' 
                       + blobUrl 
                       + '" ' + download + '><i class="iconfont">&#xe61c;<span class="file-message-download-tip">点击下载文件</span> </i></a>'
                      + '<p class="timestamp">' + getTimestamp() + '</p>');
  } else {
    $(container).addClass("message-in");
        $(container).html('<span class="message-sender">' + source + '</span>'
                        + '<a class="file-download-button" href="' 
                       + blobUrl 
                       + '" ' + download + '><i class="iconfont">&#xe61c;<span class="file-message-download-tip">点击下载文件</span> </i></a>'
                        + '<p class="timestamp">' + getTimestamp() + '</p>');
  }
  if (!chatPanel) {
    $('.chat-panel.active').children('.chat-message-board').append(container);
    messageBoardScrollToBottom($(".chat-panel.active .chat-message-board"));
  } else {
    var messageBoard = $(chatPanel).children('.chat-message-board')
    $(messageBoard).append(container);
    messageBoardScrollToBottom($(messageBoard));
  }
}


function addServiceChatingRoomPanel() {
  consoleLog('add service chating room panel', 1);
  var chatPanel = document.createElement('div');
  $(chatPanel).attr('class', 'chat-panel active');
  $(chatPanel).attr('id', 'service-chating-room');
  $(chatPanel).html('<div class="chat-panel-titlebar">'
                    + '<span class="chat-panel-title-text">客服聊天室</span>'
                    + '</div>'
                    + '<div class="chat-message-board">');
  $('.chat-panel-list').append(chatPanel);
}

function addChatPanel(fullName) {
  consoleLog('add chat panel of ' + fullName);
  var panelId = $('#' + fullName + '-custom-panel');
  if ($(panelId).length > 0) {
    $(panelId).show();
    return;
  }
  var chatPanel = document.createElement('li');
  $(chatPanel).addClass('chat-panel');
  $(chatPanel).attr('id', fullName + '-custom-panel');
  $(chatPanel).html('<div class="chat-panel-titlebar">'
                    + '<span class="chat-panel-title-text">访客<span class="chat-panel-custom-name">' 
                      + fullName.substr(0, 8)
                    + '</span>'
                    + '<span class="transmit-button">'
                    + '转接<i class="iconfont">&#xe610;</i>'
                    + '</span>'
                    + '<span class="close-chat-panel-button">'
                    + '<i class="iconfont">&#xe603;</i>'
                    + '</span>'
                    + '<span class="on-voice-prompt">'
                    + '<i class="iconfont">&#xe602;</i>'
                    + '</span>'
                    + '</span></div>'
                    + '<div class="chat-message-board">'
                    + '</div>');
  $('.chat-panel-list').append(chatPanel);
}


function showImageViewerLayer() {
  $('.img-viewer-layer').show();
}

function hideImageViewerLayer() {
  $('.img-viewer-layer').hide();
}

function addClip(clipText) {
  var clipContainer = document.createElement('div');
  $(clipContainer).addClass('clip-container');
  
  $(clipContainer).html('<a href="javascript:;" class="clip-button">'
                         + clipText
                      + '</a><a class="clip-delete-button"><i class="iconfont">&#xe603;</i></a>');
  $('.clipboard-container').prepend(clipContainer);
}


/**
 *
 * 滑轮控制左右滚动
 *
 * http://bbs.blueidea.com/thread-2781120-1-1.html
 *
 */
function chatPanelScroll() {
  var Browser = function(){
  var d_ = document,n_ = navigator,t_ = this,s_= screen;
  
    var b = n_.appName;
    var ua = n_.userAgent.toLowerCase();
    
  t_.name = "Unknow";
  
  t_.safari = ua.indexOf("safari")>-1;  // always check for safari & opera
    t_.opera = ua.indexOf("opera")>-1;    // before ns or ie
  t_.firefox = !t_.safari && ua.indexOf('firefox')>-1; // check for gecko engine  
    t_.ns = !t_.firefox && !t_.opera && !t_.safari && (b=="Netscape");
    t_.ie = !t_.opera && (b=="Microsoft Internet Explorer");
  
  t_.name = (t_.ie ? "IE" : (t_.firefox ? "Firefox" : (t_.ns ? "Netscape" : (t_.opera ? "Opera" : (t_.safari ? "Safari" : "Unknow")))));
}

var brw = new Browser();

var apDiv1 = document.getElementsByClassName("chat-panel-list")[0];
var perWidth = apDiv1.clientWidth / 10;

var mouse_wheel = function(e){
  var evt = window.event || e;
  if(evt.detail > 0 || evt.wheelDelta < 0)
    apDiv1.scrollLeft += perWidth;
  else
    apDiv1.scrollLeft -= perWidth;
}

var mouse_wheel_opera = function(e){
  //alert(window.event == e); //Opera 下，window.event 和 e 相等
  var obj = e.srcElement;
  if(obj == apDiv1){
    mouse_wheel(e);
  }
} 
  
switch(brw.name){
  case "IE":
  case "Safari":
    apDiv1.onmousewheel = mouse_wheel;
    break;
  case "Firefox":
    apDiv1.addEventListener("DOMMouseScroll", mouse_wheel, false);
    break;
  case "Opera":
    document.onmousewheel = mouse_wheel_opera;
    break;
}
}


/***********************************************************************************************************************
 *
 * XMPP functions.
 *
 **********************************************************************************************************************/

function checkIfRosterIsService(rosterItem) {
  if(rosterItem.jid.search('-service-') >= 0) {
    return true;
  }
  return false;
}

function checkIfRosterOnline(rosterItem) {
  var resources = rosterItem.resources;
  for(i in resources) {
    if(resources[i].show == 'chat') {
      return true;
    }
  }
  return false;
}

function addServiceItem(serviceFullName) {
  if($('#' + serviceFullName + '-service-item').length > 0) {
    return;
  }
  var serviceItem = document.createElement('li');
  $(serviceItem).attr('class', 'service-item');
  $(serviceItem).attr('id', serviceFullName + '-service-item');
  $(serviceItem).html('<i class="iconfont custom-avatar">&#xe605;</i>'
                          + '<a class="custom-name" href="javascript:;">' + getServiceName(serviceFullName) + '</a>');
  $('.service-list').append(serviceItem);
}

function buildServiceList() {
  var rosterItems = connection.roster.items;
  for(i = 0; i < rosterItems.length; i++) {
    var rosterItem = rosterItems[i];
    if(checkIfRosterIsService(rosterItem)) {
      addServiceItem(getFullName(rosterItem.jid));
    }
  }
}

function onGetRoster(items) {
  if (!items) {
    return;
  }
  consoleLog('get roster items ' + items.length, 1);
  buildServiceList();
}

function getJidNamespace(fullJid) {
  var idx = fullJid.search('/');
  if(idx >= 0) {
    fullJid = fullJid.substr(idx + 1);
    return fullJid;
  } else {
    return 'comm100';
  }
}

function getBareJid(fullJid) {
  var idx = fullJid.search('/');
  if(idx >= 0) {
    fullJid = fullJid.substr(0, idx);
  } else {
    idx = fullJid.search('@');
    if(idx < 0) {
      fullJid = fullJid + '@' + XMPP_HOST;
    }
  }
  return fullJid;
}

function getFullName(jid) {
  var idx = jid.search('@');
  if(idx >= 0) {
    jid = jid.substr(0, idx);
  }
  return jid;
}

function getServiceName(serviceJid) {
  var idx = serviceJid.search('-service-');
  if(idx >= 0) {
    serviceJid = serviceJid.substr(0, idx);
  }
  return serviceJid;
}

function serviceNickToJid(nick) {
  return (nick + '-service-' + siteCode + '@' + XMPP_HOST);
}


function askSubscribe(pureJid) {
  connection.send($pres({to: pureJid, type: 'subscribe'}).tree());
}

function subscribedTo(pureJid) {
  connection.send($pres({to: pureJid, type: 'subscribed'}).tree());
}

function register() {
  connection.register.connect(XMPP_HOST, onConnect);
}

function onCustomRequest(customJid) {
  sendChatMessage(customJid, '欢迎咨询');
}

function onMessage(msg) {
  var from = msg.getAttribute('from');
  from = getBareJid(from);
  var type = msg.getAttribute('type');
  consoleLog('on message from ' + from + ', type ' + type, 1);
  var peerName = getFullName(from);
  var panelId = peerName + '-custom-panel';
  var body = msg.getElementsByTagName('body')[0];
  if (from.search('-custom-') >= 0) {
    addChatPanel(peerName);
    if (type == 'chat' && body) {
      playMessageRingtone();
      appendMessage(1, Strophe.getText(body), $('#' + panelId));
      return true;
    } else if(type == 'hello') {
      onCustomRequest(from);
      return true;
    } else if(type == 'transmit' && body) {
      consoleLog('transmit from ' + Strophe.getText(body), 1);
      appendSystemMessage('访客转接自' + Strophe.getText(body), $('#' + panelId));
      return true;
    } else if(type == "fileName") {
      peerFileName = Strophe.getText(body);
      return true;
    }
  }
  if(type == 'groupchat' && body) {
    from = msg.getAttribute('from');
    from = getJidNamespace(from);
    if(from != myName) {
      appendMessage(from, Strophe.getText(body), $('#service-chating-room'));
    }
  }
  return true;
}

function onSubscribe(subs) {
  var suber = subs.getAttribute('from');
  subscribedTo(suber);
}

function onRosterLeave(pres) {
  var roster = pres.getAttribute('from');
  var fullName = getFullName(roster);
  removeChatPanel($('#' + fullName + '-custom-panel'));
  removeCustomItem(fullName);
}

function handleStatus(status) {
  /*JSON.parse(status);*/
}

function onPresence(pres) {
console.log('fffffffffffffffffffffffffffffffffffffff pres');
  console.log('on presence');
  var presType = pres.getAttribute('type');
  consoleLog('on normal presence.', 1);
  consoleLog('presence type: ' + presType, 1);
  if(presType == 'subscribe') {
    onSubscribe(pres);
    return true;
  }
  if(presType == 'unavailable') {
    onRosterLeave(pres);
    return true;
  }
  var from = pres.getAttribute('from');
  var show = pres.getElementsByTagName('show');
  consoleLog('on pres from ' + from + ', show ' + show, 1);
  if (from.search('-custom-') >= 0) {
    var fullName = getFullName(from);

       var nick = pres.getElementsByTagName('nick');
      if(nick.length == 0) {
        return true;
      }
      var status = {};
      status.nick = Strophe.getText(pres.getElementsByTagName('nick')[0]);
      status.status = Strophe.getText(pres.getElementsByTagName('status')[1]);
      status.browser = Strophe.getText(pres.getElementsByTagName('browser')[0]);
      status.system = Strophe.getText(pres.getElementsByTagName('system')[0]);
      status.ip = Strophe.getText(pres.getElementsByTagName('ip')[0]);
      status.location = Strophe.getText(pres.getElementsByTagName('location')[0]);
      status.viewingUrl = Strophe.getText(pres.getElementsByTagName('viewingUrl')[0]);
      consoleLog('prepare add custom item of ' + status.nick, 1);
      consoleLog('custom ' + from + ' info: ' + status.nick + ', ' + status.status + ', ' + status.browser + ', '+ status.system + ', '
                 + status.ip + ', ' + status.location + ', ' + status.viewingUrl, 1);
     
      addCustomItem(getFullName(from), status.nick, status.status, status.ip, status.location, status.viewingUrl, status.browser, status.system);
return true;
  } /*else if(from.search('-service-' + siteCode) >= 0) {
    var fullName = getFullName(from);
    var show = pres.getElementsByTagName('show');
    var status = Strophe.getText(pres.getElementsByTagName('status')[0]);
    addServiceItem(fullName);
    changeServiceStatus(fullName, status);
    return true;
  } 

*/
  return true;
}


var tmpIq;
function onIqResult(iq) {
  consoleLog('on iq result', 1);
  var chatXml = iq.getElementsByTagName('chat');
  consoleLog(iq.innerHTML, 3);
  tmpIq = iq;
  if(chatXml.length > 0) {
    consoleLog('iq with chat tag', 2);
    for(i = 0; i < chatXml.length; i++) {
      var chatEles = chatXml[i].children;
      var ns = chatXml[i].getAttribute('xmlns');
      if(ns == 'urn:xmpp:archive') {
        consoleLog('archive iq', 3);
        var chatter = chatXml[i].getAttribute('with');
        chatter = getFullName(chatter);
        var chatPanel = $('.chat-panel#' + chatter + 'custom-panel');
        var startTime = new Date(chatXml[i].getAttribute('start'));
        for(j = 0; j < chatEles.length; j++) {
          var chatEle = chatEles[j]
          var tagName = chatEle.tagName;
          var secs = chatEle.getAttribute('secs');
          var body = chatEle.getElementsByTagName('body')[0];
          body = Strophe.getText(body);
          if(tagName == 'to') {
            appendHistorySendMessage(chatter, body, startTime.getTime() + (secs * 1000));
          } else if(tagName == 'from') {
            appendHistoryRecieveMessage(chatter, body, startTime.getTime() + (secs * 1000));
          }
        }
      }
    }
  }
  return true;
}

function onConnect(status) {
  if (status == Strophe.Status.REGISTER) {
    connection.register.fields.username = myName;
    connection.register.fields.password = myPasswd;
    consoleLog('register with ' + myName + ', ' + myPasswd, 1);
    connection.register.submit();
  } else if (status == Strophe.Status.REGISTERED) {
    consoleLog("registered!", 1);
    connection.authenticate();
  } else if (status == Strophe.Status.CONFLICT) {
    consoleLog("Contact already existed!", 1);
  } else if (status == Strophe.Status.NOTACCEPTABLE) {
    consoleLog("Registration form not properly filled out.", 1)
  } else if (status == Strophe.Status.CONNECTING) {
    consoleLog("xmpp connecting", 1);
  } else if (status == Strophe.Status.CONNFAIL) {
    consoleLog("xmpp connect fail", 1);
  } else if (status == Strophe.Status.DISCONNECTING) {
    consoleLog("xmpp disconnecting", 1);
  } else if (status == Strophe.Status.DISCONNECTED) {
    consoleLog("xmpp disconnected", 1);
  } else if (status == Strophe.Status.CONNECTED) {
    myName = getServiceName(connection.jid);
    myFullName = getFullName(connection.jid);
    if($('.remember-me-input').attr('checked')) {
      localStorage.setItem('myJid', getBareJid(connection.jid));
      localStorage.setItem('myServicePasswd', myPasswd);
    }
    consoleLog("xmpp connected", 1);
    $('.current-service-name').html(myName);
    connection.addHandler(onMessage, null, 'message', null, null, null);
    connection.addHandler(onPresence, null, 'presence', null, null, null);
    connection.addHandler(onIqResult, null, 'iq', 'result', null, null);
    jionServiceChatRoom();
    myPres.show = 'chat';
    myPres.status = xmppPres.online;
    sendPresence();
    sendPresSchedule();
    connection.roster.get(onGetRoster, 0);
    buildPeerjs();
  }
  return true;
}


function login(jid, passwd) {
  consoleLog('login with jid ' + jid + ', passwd ' + passwd, 1);
  connection.connect(jid,
      passwd,
      onConnect);
};

/**
 * Announce presence.
 */
function sendPresence() {
  connection.send($pres().c('show', myPres.show).up().c('status', {},  myPres.status).tree());
}

/**
 * Send a text chat message to Someone.
 */
function sendChatMessage(receiverJid, textMessage) {
  connection.send($msg({to: receiverJid, from: myJid, type: 'chat'})
      .cnode(Strophe.xmlElement('body', textMessage))
      .tree());
};

function sendServiceChatMessage(textMessage) {
  connection.send($msg({to: siteCode + '@conference.' + XMPP_HOST, type: 'groupchat'}).cnode(Strophe.xmlElement('body', textMessage)).tree())
}

function pickUp(fullName) {
  var jid = fullName + '@' + XMPP_HOST;
  connection.send(
    $msg({to: jid, type: 'hello'}).tree());
}

function disconnect() {
  connection.send($pres().c('show', 'away').up().c('status', {},  'leave').tree());
  connection.disconnect();
  peerjs.disconnect();
}

function askMesshistory(jid) {
  consoleLog('askMesshistory with ' + jid, 1);
  connection.send($iq({type:'get'})
  .c('retrieve',  {xmlns:'urn:xmpp:archive', with: getBareJid(jid)})
     .c('set', {xmlns:'http://jabber.org/protocol/rsm'}).c('max', '30').tree())
}

function jionServiceChatRoom() {
  connection.send($pres({to: siteCode + '@conference.' + XMPP_HOST + '/' + myName}).tree())
}

function closeCustom(customFullName) {
  removeCustomItem(customFullName);
  removeChatPanel($('#' + fullName + '-custom-panel'));
}

function transmitTo(serviceJid, customName) {
  connection.send($msg({to: customName + '@' + XMPP_HOST, type: 'transmit'})
      .cnode(Strophe.xmlElement('body', serviceJid))
      .tree());
}


/*************************************************************************************************************
 *
 * peerjs functions.
 *
 ************************************************************************************************************/

var dataView;
var dataBlob;
var dataUrl;


  var myImgFile;
  var myFile;
  var peerjsConn;

  function sendImg() {
    var peerName = peerjsConn.peer;
    consoleLog('send img file to ' + peerName, 1);
    peerConnections[peerName]['imgConnection'].send(myImgFile);
  }

  function sendFile() {
    var peerName = peerjsConn.peer;
    consoleLog('send file to ' + peerName, 1);
    peerConnections[peerName]['fileConnection'].send(myFile);
  }


function onPeerjsConnect(conn) {
  consoleLog('on peerjs connect', 2);
  if (conn.label === 'img') {
    consoleLog('on img connect from ' + conn.peer, 1);
    imgConnectionValid(conn.peer);
    peerConnections[conn.peer]['imgConnection'];
    peerConnections[conn.peer]['imgConnection'] = conn;
    conn.on('data', function(data) {
      consoleLog('on img in connect with ' + conn.peer, 1);
      if (data.constructor === ArrayBuffer) {
        dataView = new Uint8Array(data);
        dataBlob = new Blob([dataView]);
        dataBlob = setBlobToImgType(dataBlob);
        dataUrl = window.URL.createObjectURL(dataBlob);
        appendImageMessage(1, dataUrl, $('#' + conn.peer + '-custom-panel'))
      }
    });
  } else if(conn.label == 'file') {
    consoleLog('on file connect from ' + conn.peer, 1);
    fileConnectionValid(conn.peer);
    peerConnections[conn.peer]['fileConnection'];
    peerConnections[conn.peer]['fileConnection'] = conn;
    conn.on('data', function(data) {
      consoleLog('on file in connect with ' + conn.peer, 1);
      if (data.constructor === ArrayBuffer) {
        dataView = new Uint8Array(data);
        dataBlob = new Blob([dataView]);
        dataBlob = setBlobToFileType(dataBlob, conn.label);
        dataUrl = window.URL.createObjectURL(dataBlob);
        appendFileMessage(1, dataUrl, $('#' + conn.peer + '-custom-panel'));
      }
    });
  }
}


function imgConnectionValid(peerName) {
  if(!peerConnections[peerName]) {
    peerConnections[peerName] = {};
    return false;
  }
  if(!peerConnections[peerName]['imgConnection']) {
    return false;
  }
  if(!peerConnections[peerName]['imgConnection'].open) {
    return false;
  }
  return true;
}

function fileConnectionValid(peerName) {
  if(!peerConnections[peerName]) {
    peerConnections[peerName] = {};
    return false;
  }
  if(!peerConnections[peerName]['fileConnection']) {
    return false;
  }
  if(!peerConnections[peerName]['fileConnection'].open) {
    return false;
  }
  return true;
}


function peerJsImgConnectTo(peerId) {
  var conn = peerjs.connect(peerId, { label: 'img', reliable: true });
  conn.on('open', function() {
    consoleLog('img connection with ' + peerId + ' opened', 2);
    onPeerjsConnect(conn);
    peerjsConn = conn;
  });
  conn.on('close', function() {
    consoleLog('img connect with ' + peerId + ' disconnected');
  });
  conn.on('error', function(err) { consoleLog(err, 2); });
}

function peerJsFileConnectTo(peerId) {
  var conn = peerjs.connect(peerId, { label: 'file', reliable: true });
  conn.on('open', function() {
    consoleLog('file connection with ' + peerId + ' opened',2);
    onPeerjsConnect(conn);
    peerjsConn = conn;
  });
  conn.on('error', function(err) { consoleLog(err, 2); });
  conn.on('close', function() {
    consoleLog('file connect with ' + peerId + ' disconnected', 2);
  });
}


function buildConnectionsTo(peerName) {
  if(!imgConnectionValid(peerName)) {
    peerJsImgConnectTo(peerName);
  }
  if(!fileConnectionValid(peerName)) {
    peerJsFileConnectTo(peerName);
  }
}
function buildPeerjs() {
  if(webrtcSupport) {
    peerjs = new Peer(myFullName, {
      // Set API key for cloud server (you don't need this if you're running your
      // own.
      key: 'x7fwx2kavpy6tj4i',

      // Set highest debug level (log everything!).
      debug: 3,

      // Set a logging function:
      logFunction: function() {
        var copy = Array.prototype.slice.call(arguments).join(' ');
        consoleLog(copy, 2);
      }
    });

    // Show this peer's ID.
    peerjs.on('open', function(id){
      consoleLog('peer on open, id: ' + id, 2);
    });

    peerjs.on('error', function(err) {
      consoleLog(err, 2);
    });

    peerjs.on('connection', onPeerjsConnect);
  }
}

/*****************************************************************************************************************
 *
 * start up.
 *
 *****************************************************************************************************************/


$(document).ready(function () {


  /*****************************************************************************************************************
   *
   * UI effects
   *
   *****************************************************************************************************************/
  $(".contacts-container").tabs();
  $(".chat-panel-list").sortable();

  updateLivetime();

  generateEmojiItems();

  siteCode = new RegExp(".{8}\$").exec(location.pathname)[0];
  $('.top-logo-container img').attr('src', 'http://comm100.lsu.pw/logoImage/' + siteCode);
  $('.login-layer-title-logo').attr('src', 'http://comm100.lsu.pw/logoImage/' + siteCode);
  connection = new Strophe.Connection(BOSH_SERVICE);
  /*connection.connect('test@49.lsu.pw', 'fortest', onConnect);
   peerJid = 'cc1@49.lsu.pw';*/
  if(logLevel >= 3) {
    $('#logbox').show();
    connection.rawInput = function (data) {
      $('#logbox').append('<div></div>').append(document.createTextNode('recv: ' + data));
    };
    connection.rawOutput = function (data) {
      $('#logbox').append('<div></div>').append(document.createTextNode('send: ' + data));
    };
  }

  queryClips();

  myJid = localStorage.getItem('myJid');
  myPasswd = localStorage.getItem('myServicePasswd');
  if(myJid && myPasswd) {
    login(myJid, myPasswd);
    hideLoginLayer();
    addServiceChatingRoomPanel();
  }

  $('body').on('click', '.send-button', function () {
    var message = $('.text-input').val();
    if (message != '' && $('.chat-panel.active').length > 0 && connection.connected) {
      if($('.chat-panel.active#service-chating-room').length > 0) {
        sendServiceChatMessage(message);
        appendMessage(2, message);
        $('.text-input').val('');
      } else {
        var peerName =  $('.chat-panel.active').attr('id');
        peerName = peerName.substr(0, peerName.search('-custom-panel'));
        var peerJid = peerName + '@' + XMPP_HOST;
        sendChatMessage(peerJid, message);
        appendMessage(2, message);
        $('.text-input').val('');
      }
    }
  });

  $('body').on('change', '#img-input', function() {
    myImgFile = $(this)[0].files;
    myImgFile = myImgFile[0];
    if($('.chat-panel.active').length > 0 && $('.chat-panel.active#service-chating-room').length == 0) {
      var peerName = $('.chat-panel.active').attr('id');
      peerName = peerName.substr(0, peerName.search('-custom-panel'));
      consoleLog('prepare send image to ' + peerName, 1);
      appendImageMessage(2, window.URL.createObjectURL(myImgFile), $('.chat-panel.active'));
      if(!imgConnectionValid(peerName)) {
        buildConnectionsTo(peerName);
        peerjsConn = peerConnections[peerName]['imgConnection'];
        setTimeout('sendImg()', 1500);
      } else {
        peerjsConn = peerConnections[peerName]['imgConnection'];
        sendImg();
      }
    }
    $(this).val('');
  });


  $('body').on('change', '#file-input', function() {
    myFile = $(this)[0].files;
    myFile = myFile[0];
    if($('.chat-panel.active').length > 0 && $('.chat-panel.active#service-chating-room').length == 0) {
      var peerName = $('.chat-panel.active').attr('id');
      peerName = peerName.substr(0, peerName.search('-custom-panel'));
      consoleLog('prepare send file to ' + peerName, 1);
      connection.send($msg({to: peerName + '@' + XMPP_HOST, type: 'fileName'})
      .cnode(Strophe.xmlElement('body', myFile.name))
      .tree());
      appendSystemMessage('你已发送一个文件');
      if(!fileConnectionValid(peerName)) {
        buildConnectionsTo(peerName);
        peerjsConn = peerConnections[peerName]['fileConnection'];
        setTimeout('sendFile()', 1500);
      } else {
        peerjsConn = peerConnections[peerName]['fileConnection'];
        setTimeout('sendFile()', 500);
      }
    }
    $(this).val('');
  });

  $('.img-button').on('click', function() {
    consoleLog('img-button clicked', 1);
    $('#img-input').click();
  });

  $('.file-button').on('click', function() {
    consoleLog('file-button clicked', 1);
    $('#file-input').click();
  });

  $('body').on('click', '.close-chat-panel-button', function () {
    hideChatPanel($(this).parents('.chat-panel'));
  });

  $('body').on('click', '.chat-panel', function () {
    $('.chat-panel.active').removeClass('active');
    $(this).addClass('active');
  });

  $('body').on('click', '.custom-name', function () {
    var customItem = $(this).parents('.custom-item')[0];
    var fullName = $(customItem).attr('id');
    fullName = fullName.substr(0, fullName.search('-custom-item'));
 /*   if ($(this).siblings('.custom-status.' + xmppPres.chating).length > 0) {
      return;
    }*/
    askMesshistory(fullName + '@' + XMPP_HOST);
    addChatPanel(fullName);
    pickUp(fullName);
    buildConnectionsTo(fullName);
  });

  $('body').on('keypress', '.text-input', function (event) {
    if (event.keyCode == 13) {
      $('.send-button').click();
    }
  });

  $('body').on('keypress', '.userpasswd-input', function (event) {
    if (event.keyCode == 13) {
      $('.login-botton').click();
    }
  });

  $('body').on('click', '.login-button', function() {
    myName = $('.username-input').val();
    myFullName = myName + '-service-' + siteCode;
    myJid = myFullName + '@' + XMPP_HOST;
    myPasswd = $('.userpasswd-input').val();
    if(myName && myPasswd) {
      login(myJid, myPasswd);
      hideLoginLayer();
      addServiceChatingRoomPanel();
      $('.username-input').val('');
      $('.userpasswd-input').val('');
    }
  }); 

  $('body').on('click', '.chat-image', function () {
    var imgUrl = $(this).attr('src');
    $('.img-show').attr('src', imgUrl);
    showImageViewerLayer();
  });


  $('body').on('click', '.img-viewer-close-button', function () {
    hideImageViewerLayer();
  });  

  $('body').on('click', '.clip-button', function () {
    var container = $(this).parents('.clip-container');
    var clip = $(this).html();
    var input = $('.text-input').val();
    $('.text-input').val(input + clip);
  });

  $('body').on('click', '.clip-delete-button', function () {
    var container = $(this).parents('.clip-container')[0]
    var clip = $(container).children('.clip-button')[0];
    clip = $(clip).html();
    localStorage.removeItem('clip-' + clip);
    $(container).remove();
  });

  $('body').on('click', '.add-clip-button', function () {
    if($('#add-clip-input').attr('status') == 'show') {
      var clip = $('#add-clip-input').val();
      if(clip == '') return;
      saveClip(clip);
      addClip(clip);
      $('#add-clip-input').attr('status', 'hide');
      $('#add-clip-input').hide();
      var clip = $('#add-clip-input').val('');
    } else {
      $('#add-clip-input').attr('status', 'show');
      $('#add-clip-input').show();
    }
  });

  $('body').on('click', '..message-audio-play-button', function() {
    $(this).siblings('audio')[0].play()
  });

  $('body').on('click', '.image-message', function () {
    var imgUrl = $(this).attr('src');
    $('.img-show').attr('src', imgUrl);
    showImageViewerLayer();
  });

  $('body').on('hover', '.emoji-button', function() {
    var emojiBoxX = $('.emoji-button')[0].offsetLeft + 80;
    var emojiBoxY = $('.emoji-button')[0].offsetTop + 210;
    var emojiBox = $('#emoji-box');
    emojiBox.css('left', emojiBoxX);
    emojiBox.css('top', emojiBoxY);
    $('#emoji-box').show();
  });

  $('body').on('mouseleave', '#emoji-box', function() {
    $('#emoji-box').hide();
  });

  $('body').on('click', ".emoji-grid-cell", function() {
    $('#emoji-box').hide();
    var inputText = $('.text-input').val();
    var emojiText = '[emoji_' + /\d+/.exec($(this).children('.emoji-image').attr('src')) + ']';
    $('.text-input').val(inputText + emojiText);
  });

  $('body').on('click', '.close-chat-panel-button', function() {
    $(this).parents('.chat-panel').hide();
  });

  $('body').on('click', '.delete-custom-buttom', function() {
    var customItem = $(this).parents('.custom-item')[0];
    var fullName = $(customItem).attr('id');
    fullName = fullName.substr(0, fullName.search('-custom-item'));
    closeCustom(fullName);
  });

  $('body').on('change', '.currents-serice-online-status', function() {
    var status = $(this).val();
    if(status == 'exit') {
      localStorage.removeItem('myJid');
      localStorage.removeItem('myServicePasswd');
      disconnect();
      showLoginLayer();
      $('.chat-panel-list').html('');
      $('.service-list').html('');
      $('.custom-list').html('');
    }
  });

  $('body').on('click', '.transmit-button', function() {
    transmitItem = $(this).parents('.chat-panel');
    var transmitItemLIst = $('#transmit-service-list-container');
    $(transmitItemLIst).html('');
    var itemListHtml = '';
    for(i = 0; i < connection.roster.items.length; i++) {
      var rosterItem = connection.roster.items[i];
      if(checkIfRosterIsService(rosterItem) && checkIfRosterOnline(rosterItem)) {
        itemListHtml = itemListHtml 
                     + '<div class="transmit-service-item" id="'
                     + getFullName(rosterItem.jid) + 'transmit-service'
                     + '">' + getServiceName(rosterItem.jid) + '</div>';
      }
    }
    if(!itemListHtml) {
      itemListHtml = '无其他客服在线';
    }
    $(transmitItemLIst).html(itemListHtml);
    var positionX = $(this)[0].offsetLeft + $(this).parents('.chat-panel')[0].offsetLeft;
    var positionY = $(this)[0].offsetTop + $(this).parents('.chat-panel')[0].offsetTop + 20;
    var serviceList = $('#transmit-service-list-container');
    serviceList.css('left', positionX);
    serviceList.css('top', positionY);
    $(serviceList).show();
  });

  $('body').on('click', '.transmit-service-item', function() {
    $('#transmit-service-list-container').hide();
    var serviceNick = $(this).html();
    var customName = $(transmitItem).attr('id');
    customName = customName.substr(0, customName.search('-custom-panel'));
    transmitTo(serviceNickToJid(serviceNick), customName);
  });

  $('body').on('mouseleave', '#transmit-service-list-container', function() {
    $(this).hide();
  });


  chatPanelScroll();

  checkWebrtcSupport();

  window.onunload = window.onbeforeunload = function(e) {
    disconnect();
    if (!!peer && !peer.destroyed) {
      peer.destroy();
    }
  };
  

});
